
package com.hlkj.pay.util;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.hlkj.pay.common.constants.BaseConstants;
import net.dreamlu.mica.core.utils.StringPool;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * @author HlpayTeam
 * @date 2024/09/14 9:49
 */
public class DateUtils {

    public static String getDateString(String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return dateFormat.format(new Date());
    }

    public static Long getCurrentTime() {
        return DateUtil.current();
    }

    public static String cardDataFormat(String dataString, String pattern) {
        if (dataString.contains("长期")) {
            return BaseConstants.MAX_DATA_STRING;
        }
        return dataFormat(dataString, pattern);
    }

    public static Long shanghaiDate(String yyyyMMddHHmmss) {
        // 解析 LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse(yyyyMMddHHmmss, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();

    }

    public static Long shanghaiDate(String date, DateTimeFormatter formatter) {
        // 解析 LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse(date, formatter);
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();
    }

    public static Long shanghaiDate(LocalDateTime dateTime) {
        // 解析 LocalDateTime
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();

    }
    public static Long shanghaiDate(String date, String pattern) {
        // 解析 LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(pattern));
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();
    }
    public static Long shanghaiLocalDate(String date, String pattern) {
        // 解析 LocalDateTime
        LocalDate dateTime = LocalDate.parse(date, DateTimeFormatter.ofPattern(pattern));
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime =dateTime.atStartOfDay().atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();
    }

    public static Long shanghaiStartDate(String data, String pattern) {
        if (StringUtils.isEmpty(pattern)) {
            return null;
        }
        if(DatePattern.NORM_DATE_PATTERN.equals(pattern)){
            data=data+" 00:00:00";
        }else if(DatePattern.NORM_MONTH_PATTERN.equals(pattern)){
            data=data+"-01 00:00:00";
        }else if(DatePattern.NORM_YEAR_PATTERN.equals(pattern)){
            data=data+"-01-01 00:00:00";
        }
        // 解析 LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse(data, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();
    }
    public static Long shanghaiStartDate(LocalDateTime dateTime ) {
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();

    }
    public static Long shanghaiEndDate(String data, String pattern) {
        if (StringUtils.isEmpty(pattern)) {
            return null;
        }
        if(DatePattern.NORM_DATE_PATTERN.equals(pattern)){
            data=data+" 23:59:59";
        }else if(DatePattern.NORM_MONTH_PATTERN.equals(pattern)){
            data=data+"-31 23:59:59";
        }else if(DatePattern.NORM_YEAR_PATTERN.equals(pattern)){
            data=data+"-12-31 23:59:59";
        }
        // 解析 LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse(data, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
        // 转换为东八区 ZonedDateTime
        ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));
        // 获取时间戳的毫秒值
        return zonedDateTime.toInstant().toEpochMilli();

    }
    public static String dateToString(Long timestamp, String pattern) {
        // 将时间戳转换为LocalDateTime
        LocalDateTime dateTime = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.of("Asia/Shanghai"))  // 使用系统默认时区
                .toLocalDateTime();
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }
    public static LocalDateTime dateToLocalDateTime(Long timestamp) {
        // 将时间戳转换为LocalDateTime
        LocalDateTime dateTime = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.of("Asia/Shanghai"))  // 使用系统默认时区
                .toLocalDateTime();
        return dateTime;
    }
    public static boolean isSameDay(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        // 比较年份、月份、日期是否相同
        return dateTime1.getYear() == dateTime2.getYear() &&
                dateTime1.getMonth() == dateTime2.getMonth() &&
                dateTime1.getDayOfMonth() == dateTime2.getDayOfMonth();
    }
    public static boolean isSameWeek(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        // 使用 WeekFields 获取周数，传入 Locale 为默认区域
        WeekFields weekFields = WeekFields.of(Locale.getDefault());

        int week1 = dateTime1.get(weekFields.weekOfWeekBasedYear());
        int week2 = dateTime2.get(weekFields.weekOfWeekBasedYear());
        int year1 = dateTime1.getYear();
        int year2 = dateTime2.getYear();

        // 判断年份和周数是否相同
        return year1 == year2 && week1 == week2;
    }
    public static boolean isSameMonth(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        // 比较年份和月份是否相同
        return dateTime1.getYear() == dateTime2.getYear() && dateTime1.getMonth() == dateTime2.getMonth();
    }
    public static Date timestampToDate(Long timestamp) {
        // 将时间戳转换为 Instant 对象
        Instant instant = Instant.ofEpochMilli(timestamp);
        // 将 Instant 转换为东八区（上海时区）的 ZonedDateTime
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Shanghai"));
        // 将 ZonedDateTime 转换为 java.util.Date
        return Date.from(zonedDateTime.toInstant());
    }

    public static String yyyyMMddAddDash(String dataString) {
        if(!StringUtils.hasText(dataString)){
            return null;
        }
        DateTime yyyyMMdd = com.hlkj.framework.common.util.date.DateUtils.parse(dataString, DateTimeFormatter.ofPattern("yyyyMMdd"));
        return com.hlkj.framework.common.util.date.DateUtils.format(yyyyMMdd, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    public static String yyyyMMddDelDash(String dataString) {
        DateTime yyyyMMdd = com.hlkj.framework.common.util.date.DateUtils.parse(dataString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return com.hlkj.framework.common.util.date.DateUtils.format(yyyyMMdd, DateTimeFormatter.ofPattern("yyyyMMdd"));
    }

    public static String dataFormat(String dataString, String pattern) {
        String[] split = dataString.split(pattern);
        String year = split[0];
        String month = split[1];
        String day = split[2];
        month = addZero(month);
        day = addZero(day);
        return year + StringPool.DASH + month + StringPool.DASH + day;
    }

    public static String addZero(String value) {
        if (value.length() < 2) {
            return StringPool.ZERO + value;
        }
        return value;
    }

    public static Long betweenMonth(String startTime, String endTime) {
        Date date1 = DateUtil.parse(startTime);
        Date date2 = DateUtil.parse(endTime);
        return DateUtil.betweenMonth(date1, date2, true);
    }

    public static Long betweenDay(String startTime, String endTime) {
        Date date1 = DateUtil.parse(startTime);
        Date date2 = DateUtil.parse(endTime);
        return DateUtil.betweenDay(date1, date2, true);
    }

    public static String lastDayOfMonth(String currentDate) {
        Date date1 = DateUtil.parse(currentDate);
        return DateUtil.formatDate(DateUtil.endOfMonth(date1));
    }

    public static String offsetDay(String currentDate, String pattern, Integer days) {
        Date date = DateUtil.parse(currentDate);
        Date retDate = DateUtil.offsetDay(date, days);
        return DateUtil.format(retDate, pattern);
    }

    public static boolean validateDate(String dateString, String pattern) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
            formatter.parse(dateString);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static String formatDate(String startTime, String fromPattern, String pattern) {
        var startDate = DateUtil.parse(startTime, fromPattern);
        return DateUtil.format(startDate, pattern);
    }

    public static String formatWeek(String startTime) {
        var startDate = DateUtil.parse(startTime, DatePattern.NORM_DATE_PATTERN);
        return formatWeek(startDate);
    }

    public static String formatWeek(Date startDate) {
        int weekOfYear = DateUtil.weekOfYear(startDate);
        Date firstDayOfWeek = DateUtil.endOfWeek(startDate);
        int weekBelongYear = DateUtil.year(firstDayOfWeek);
        return String.format("%04d-%02d周", weekBelongYear, weekOfYear);
    }

    /**
     * 用于生成连续类型的日期key
     *
     * @param startTime
     * @param type 日，周，月
     * @param stepLength
     * @return
     */
    public static List<String> createDates(String startTime, Integer type, Integer stepLength) {
        //type 1 日，2周，3月，4年
        List<String> dateList = new ArrayList<>();
        // 将字符串转换为日期
        var startDate = DateUtil.parse(startTime, DatePattern.NORM_DATE_PATTERN);
        while (stepLength-- > -1) {
            switch (type) {
                case 1:
                    dateList.add(DateUtil.format(startDate, DatePattern.NORM_DATE_PATTERN));
                    startDate = DateUtil.offsetDay(startDate, -1);
                    break;
                case 2:
                    dateList.add(DateUtils.formatWeek(startDate));
                    startDate = DateUtil.offsetWeek(startDate, -1);
                    break;
                case 3:
                    dateList.add(DateUtil.format(startDate, DatePattern.NORM_MONTH_PATTERN));
                    startDate = DateUtil.offsetMonth(startDate, -1);
                    break;
            }
        }
        return dateList;
    }

    public static void main(String[] args) {
//        DateUtils.createDates("2025-01-31", 2, 5);
        System.out.println(DateUtils.createDates("2025-01-31", 1, 5));  // 输出如：2023-20
    }
}
